#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include <regex.h>
#include <glib.h>
#include "ogg_dec.h"
#include "library.h"
#include "gui.h"
#include "debug.h"

struct find_element {
  char *name;
  int found;
};

gboolean find_element (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, struct find_element *element)
{
  gchar *name;

  gtk_tree_model_get(model, iter, COL_LIB_NAME, &name, -1);
  if (!strcmp(element->name, name)) 
    element->found = 1;

  g_free(name);

  if (element->found) return TRUE;
  else return FALSE;
}

int library_refresh_tree(GtkTreeView *tree, const char *library_path, int incremental)
{
  GtkListStore *store;
  DIR *library_dir;
  struct dirent *file;
  regex_t regex;
  regmatch_t match[2];

  DEBUG_ENTER("library_refresh_tree");
  store = GTK_LIST_STORE(gtk_tree_view_get_model(tree));
  if (!incremental)
    gtk_list_store_clear(store);

  library_dir = opendir(library_path);
  if (library_dir == NULL) {
    mkdir(library_path, 0770);
    library_dir = opendir(library_path);
    if (library_dir == NULL)
      return ERR_OPEN;
  }

  regcomp(&regex, "\\(.*\\)\\.ogg", REG_ICASE);
  while ((file = readdir(library_dir))) {
    if (regexec(&regex, file->d_name, 2, match, 0) == 0) {
      GtkTreeIter iter;
      ogg_dec_t ogg_dec;
      struct stat status;
      struct tm *tm;
      char *name, *path, *length, *date;
      int hours, minutes, seconds;

      name = g_strndup(file->d_name, match[1].rm_eo);
      path = g_strdup_printf("%s/%s",library_path, file->d_name);

      /* check if this file exist on listview */
      if (incremental) {
	struct find_element element;
	element.name = name;
	element.found = 0;
	gtk_tree_model_foreach (GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)find_element, &element);
	if (element.found) {
	  g_free(name);
	  g_free(path);
	  continue;
	}
      }

      /* length of the stream */
      ogg_dec_open(&ogg_dec, path);
      seconds = ogg_dec_length(&ogg_dec);
      ogg_dec_close(&ogg_dec);

      hours = floor(seconds / 3600);
      seconds -= hours * 3600;
      minutes = floor(seconds / 60);
      seconds -= minutes * 60;
      length = g_strdup_printf("%02d:%02d:%02d",hours,minutes,seconds);

      /* last modification file */
      stat(path, &status);
      tm = localtime(&status.st_mtime);
      date = g_strdup_printf("%04d/%02d/%02d, %02d:%02d",
			     tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,
			     tm->tm_hour+1,tm->tm_min+1);

      /* append to list */
      gtk_list_store_append(store, &iter);
      gtk_list_store_set(store, &iter, 
			 COL_LIB_NAME, name, 
			 COL_LIB_DATE, date,
			 COL_LIB_LENGTH, length,
			 -1);
      /* free */
      g_free(name);
      g_free(path);
      g_free(length);
      g_free(date);
    }
  }

  regfree(&regex);
  closedir(library_dir);
  return 0;
}

char *library_gen_name(const char *library_path)
{
  static char file_path[255];
  regex_t regex;
  regmatch_t match[2];
  DIR *library_dir;
  struct dirent *file;
  int last = 0;

  library_dir = opendir(library_path);
  if (library_dir == NULL) {
    mkdir(library_path, 0770);
    library_dir = opendir(library_path);
    if (library_dir == NULL)
      return NULL;
  }  

  /* read last number of record*.ogg file */
  regcomp(&regex, "record\\([0-9]*\\)\\.ogg", REG_ICASE);
  while ((file = readdir(library_dir))) {
    if (regexec(&regex, file->d_name, 2, match, 0) == 0) {
      char *number = g_strndup(file->d_name + match[1].rm_so, match[1].rm_eo - match[1].rm_so);
      if (last < atoi(number))
	last = atoi(number);
      g_free(number);
    }  
  }
  closedir(library_dir);
  regfree(&regex);

  g_sprintf(file_path,"%s/record%03d.ogg",library_path,last+1);
  return file_path;
}
